﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using RBAC.DAL.Dal;
using RBAC.DAL.Entities;
using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using RBAC.Service.Dto;
using RBAC.DAL.Models;
using System.ServiceModel.Activation;
using AutoMapper;
using RBAC.Service.Util;
using RBAC.Service;
using RBAC.DAL.Mappers;

namespace RBAC.Service
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select Service.svc or Service.svc.cs at the Solution Explorer and start debugging.
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Service : IService
    {
        private ISession _session;
        private ISessionFactory _sessionFactory;
        // hack Dynamic T4
        private const int ProjectId = 1;

        public Service()
        {
            NHibernateConfig();
        }

        private void NHibernateConfig()
        {
            var appReader = new System.Configuration.AppSettingsReader();
            var connectionString = Convert.ToString(appReader.GetValue("connectionString", typeof(string)));
            // hack:temp
            var mappingScriptPath = AppDomain.CurrentDomain.BaseDirectory + "/db_mappings";
            if (!Directory.Exists(mappingScriptPath))
                Directory.CreateDirectory(mappingScriptPath);

            _sessionFactory = Fluently.Configure()
                .Database(
                    MsSqlConfiguration.MsSql2008
                        .ConnectionString(@connectionString))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
                //.Mappings(x => x.AutoMappings.Add(AutoMap.AssemblyOf<User>().Where(t => t.Namespace != null && t.Namespace.EndsWith("Entities"))).ExportTo(@mappingScriptPath))
                //.ExposeConfiguration(BuildSchema) // ********** ใช้ครั้งแรกเท่านั้น (กรณียังไม่มี Table)  
                .BuildSessionFactory();
            _session = _sessionFactory.OpenSession();
        }

        public void InvokeDB()
        {
            var appReader = new System.Configuration.AppSettingsReader();
            var connectionString = Convert.ToString(appReader.GetValue("connectionString", typeof(string)));
            // hack:temp
            var mappingScriptPath = AppDomain.CurrentDomain.BaseDirectory + "/db_mappings";
            if (!Directory.Exists(mappingScriptPath))
                Directory.CreateDirectory(mappingScriptPath);

            _sessionFactory = Fluently.Configure()
                .Database(
                    MsSqlConfiguration.MsSql2008
                        .ConnectionString(@connectionString))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
                .ExposeConfiguration(BuildSchema) // ********** ใช้ครั้งแรกเท่านั้น (กรณียังไม่มี Table)  
                .BuildSessionFactory();
            _session = _sessionFactory.OpenSession();

            //InitialDb();
        }

        private void BuildSchema(Configuration config)
        {
            new SchemaExport(config).Create(false, true);
        }

        #region User methods

        public ResponseDto<UserDto> AddUser(UserDto arg)
        {
            var result = new ResponseDto<UserDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<UserDto, User>(arg);

                    var obj = UserConvertToModel(arg);

                    var dal = new UserDAL(_session, ProjectId);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<User, UserDto>(obj);
                    result.Data = UserConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<UserDto> DeleteUser(List<string> arg)
        {
            var result = new ResponseDto<UserDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new UserDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<UserDto>> GetAllUser(GetAllUserRequestDto arg)
        {
            var result = new ResponseDto<List<UserDto>>();
            var list = new List<User>();
            try
            {
                UserSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllUserRequestDto, UserSearch>(arg);
                    search = UserConvertToSearchModel(arg);
                }

                using (_session)
                {
                    var dal = new UserDAL(_session, ProjectId);
                    list = dal.GetAll(search);

                    result.Data = new List<UserDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<User, UserDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(UserConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<UserDto> UpdateUser(UserDto arg)
        {
            var result = new ResponseDto<UserDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<UserDto, User>(arg);
                    var obj = UserConvertToModel(arg);

                    var dal = new UserDAL(_session, ProjectId);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<User, UserDto>(obj);
                    result.Data = UserConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistUser(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new UserDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new UserSearch { Username = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private UserDto UserConvertToDto(User arg)
        {
            Mapper.CreateMap<User, UserDto>();
            Mapper.CreateMap<Role, RoleDto>();
            Mapper.CreateMap<Permission, PermissionDto>();
            Mapper.CreateMap<Function, FunctionDto>();
            Mapper.CreateMap<Domain, DomainDto>();
            Mapper.CreateMap<BaseEntity, BaseDto>();
            var dto = Mapper.Map<User, UserDto>(arg);
            return dto;

            //UserDto result = new UserDto();
            //if (arg != null)
            //{
            //    result.Id = arg.Id;
            //    result.Username = arg.Username;
            //    result.Password = arg.Password;
            //    result.Email = arg.Email;
            //    result.Mobile = arg.Mobile;

            //    if (arg.Role != null)
            //    {
            //        //RoleDto temp = new RoleDto();
            //        //temp.Id = arg.Role.Id;

            //        //temp.RoleCode = arg.Role.RoleCode;

            //        //temp.RoleName = arg.Role.RoleName;

            //        //temp.Description = arg.Role.Description;

            //        ////temp.CreateDate = arg.Role.CreateDate;

            //        ////temp.RoleStatus = arg.Role.RoleStatus;

            //        //result.Role = temp;
            //        result.Role = RoleConvertToDto(arg.Role);
            //    }
            //    //result.UserStatus = arg.UserStatus;
            //    result.CreateDate = arg.CreateDate;
            //    result.CreateById = arg.CreateById;
            //    result.IsActive = arg.IsActive;
            //}
            //return result;
        }

        private User UserConvertToModel(UserDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<UserDto, User>();

            Mapper.CreateMap<RoleDto, Role>();
            User result = Mapper.Map<UserDto, User>(arg);



            //if (result.Role != null)
            //{
            //    result.Role = (Role)_session.Get("Role", arg.Role.Id);
            //}


            return result;
        }

        private UserSearch UserConvertToSearchModel(GetAllUserRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllUserRequestDto, UserSearch>();
            UserSearch result = Mapper.Map<GetAllUserRequestDto, UserSearch>(arg);
            return result;
        }
        #endregion

        #region Role methods

        public ResponseDto<RoleDto> AddRole(RoleDto arg)
        {
            var result = new ResponseDto<RoleDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<RoleDto, Role>(arg);

                    var obj = RoleConvertToModel(arg);

                    var dal = new RoleDAL(_session, ProjectId);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Role, RoleDto>(obj);
                    result.Data = RoleConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<RoleDto> DeleteRole(List<string> arg)
        {
            var result = new ResponseDto<RoleDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new RoleDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<RoleDto>> GetAllRole(GetAllRoleRequestDto arg)
        {
            var result = new ResponseDto<List<RoleDto>>();
            var list = new List<Role>();
            try
            {
                RoleSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllRoleRequestDto, RoleSearch>(arg);
                    search = RoleConvertToSearchModel(arg);
                }

                using (_session)
                {
                    var dal = new RoleDAL(_session, ProjectId);
                    list = dal.GetAll(search);

                    result.Data = new List<RoleDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<Role, RoleDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(RoleConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<RoleDto> UpdateRole(RoleDto arg)
        {
            var result = new ResponseDto<RoleDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<RoleDto, Role>(arg);
                    var obj = RoleConvertToModel(arg);

                    var dal = new RoleDAL(_session, ProjectId);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Role, RoleDto>(obj);
                    result.Data = RoleConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistRole(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new RoleDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new RoleSearch { RoleCode = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private RoleDto RoleConvertToDto(Role arg)
        {
            RoleDto result = new RoleDto();
            if (arg != null)
            {
                result.Id = arg.Id;
                result.RoleCode = arg.RoleCode;
                result.RoleName = arg.RoleName;
                result.Description = arg.Description;
                result.CreateById = arg.CreateById;
                result.IsActive = arg.IsActive;
                result.CreateDate = arg.CreateDate;
                //result.CreateDate = arg.CreateDate;
                //result.RoleStatus = arg.RoleStatus;
            }
            return result;
        }

        private Role RoleConvertToModel(RoleDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<RoleDto, Role>();
            Mapper.CreateMap<PermissionDto, Permission>();
            Mapper.CreateMap<FunctionDto, Function>();
            Mapper.CreateMap<UserDto, User>();
            Role result = Mapper.Map<RoleDto, Role>(arg);




            return result;
        }

        private RoleSearch RoleConvertToSearchModel(GetAllRoleRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllRoleRequestDto, RoleSearch>();
            RoleSearch result = Mapper.Map<GetAllRoleRequestDto, RoleSearch>(arg);
            return result;
        }
        #endregion

        #region Permission methods

        public ResponseDto<PermissionDto> AddPermission(PermissionDto arg)
        {
            var result = new ResponseDto<PermissionDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<PermissionDto, Permission>(arg);

                    var obj = PermissionConvertToModel(arg);

                    var dal = new PermissionDAL(_session, ProjectId);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Permission, PermissionDto>(obj);
                    result.Data = PermissionConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<PermissionDto> DeletePermission(List<string> arg)
        {
            var result = new ResponseDto<PermissionDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new PermissionDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<PermissionDto>> GetAllPermission(GetAllPermissionRequestDto arg)
        {
            var result = new ResponseDto<List<PermissionDto>>();
            var list = new List<Permission>();
            try
            {
                PermissionSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllPermissionRequestDto, PermissionSearch>(arg);
                    search = PermissionConvertToSearchModel(arg);

                    //get ค่าแม่ของ  Permission
                    if (arg.RoleId.HasValue)
                    {
                        search.Role = _session.Get<Role>(arg.RoleId.GetValueOrDefault());
                    }
                    _session.Clear();
                }

                using (_session)
                {
                    var dal = new PermissionDAL(_session, ProjectId);
                    list = dal.GetAll(search);

                    result.Data = new List<PermissionDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<Permission, PermissionDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(PermissionConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<PermissionDto> UpdatePermission(PermissionDto arg)
        {
            var result = new ResponseDto<PermissionDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<PermissionDto, Permission>(arg);
                    var obj = PermissionConvertToModel(arg);

                    var dal = new PermissionDAL(_session, ProjectId);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Permission, PermissionDto>(obj);
                    result.Data = PermissionConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistPermission(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new PermissionDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new PermissionSearch { PermissionName = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private PermissionDto PermissionConvertToDto(Permission arg)
        {
            PermissionDto result = new PermissionDto();
            if (arg != null)
            {
                result.Id = arg.Id;
                result.PermissionName = arg.PermissionName;
                result.Description = arg.Description;
                //result.CreateDate = arg.CreateDate;
                if (arg.Role != null)
                {
                    //RoleDto temp = new RoleDto();
                    //temp.Id = arg.Role.Id;

                    //temp.RoleCode = arg.Role.RoleCode;

                    //temp.RoleName = arg.Role.RoleName;

                    //temp.Description = arg.Role.Description;

                    //temp.CreateDate = arg.Role.CreateDate;

                    //temp.RoleStatus = arg.Role.RoleStatus;
                    //result.Role = temp;

                    result.Role = RoleConvertToDto(arg.Role);

                }
                if (arg.Function != null)
                {
                    //FunctionDto temp = new FunctionDto();
                    //temp.Id = arg.Function.Id;

                    //temp.FuncName = arg.Function.FuncName;

                    //temp.Description = arg.Function.Description;

                    //temp.FunctionStatus = arg.Function.FunctionStatus;

                    //temp.FunctionName = arg.Function.FunctionName;

                    //result.Function = temp;
                    result.Function = FunctionConvertToDto(arg.Function);
                }
                //result.PermissionStatus = arg.PermissionStatus;
                if (arg.RoleLookup != null)
                {
                    //RoleDto temp = new RoleDto();
                    //temp.Id = arg.RoleLookup.Id;

                    //temp.RoleCode = arg.RoleLookup.RoleCode;

                    //temp.RoleName = arg.RoleLookup.RoleName;

                    //temp.Description = arg.RoleLookup.Description;

                    //temp.CreateDate = arg.RoleLookup.CreateDate;

                    //temp.RoleStatus = arg.RoleLookup.RoleStatus;

                    //result.RoleLookup = temp;

                    result.RoleLookup = RoleConvertToDto(arg.RoleLookup);
                }
                result.CreateById = arg.CreateById;
                result.IsActive = arg.IsActive;
                result.CreateDate = arg.CreateDate;
            }
            return result;
        }

        private Permission PermissionConvertToModel(PermissionDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<PermissionDto, Permission>();
            Mapper.CreateMap<RoleDto, Role>();
            Mapper.CreateMap<FunctionDto, Function>();
            Mapper.CreateMap<RoleDto, Role>();
            Mapper.CreateMap<UserDto, User>();
            Permission result = Mapper.Map<PermissionDto, Permission>(arg);



            if (result.Role != null)
            {
                result.Role = (Role)_session.Get("Role", arg.Role.Id);
            }

            if (result.Function != null)
            {
                result.Function = (Function)_session.Get("Function", arg.Function.Id);
            }

            if (result.RoleLookup != null)
            {
                result.RoleLookup = (Role)_session.Get("Role", arg.RoleLookup.Id);
            }


            return result;
        }

        private PermissionSearch PermissionConvertToSearchModel(GetAllPermissionRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllPermissionRequestDto, PermissionSearch>();
            PermissionSearch result = Mapper.Map<GetAllPermissionRequestDto, PermissionSearch>(arg);
            return result;
        }
        #endregion

        #region Function methods

        public ResponseDto<FunctionDto> AddFunction(FunctionDto arg)
        {
            var result = new ResponseDto<FunctionDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<FunctionDto, Function>(arg);

                    var obj = FunctionConvertToModel(arg);

                    var dal = new FunctionDAL(_session, ProjectId);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Function, FunctionDto>(obj);
                    result.Data = FunctionConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<FunctionDto> DeleteFunction(List<string> arg)
        {
            var result = new ResponseDto<FunctionDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new FunctionDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<FunctionDto>> GetAllFunction(GetAllFunctionRequestDto arg)
        {
            var result = new ResponseDto<List<FunctionDto>>();
            var list = new List<Function>();
            try
            {
                FunctionSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllFunctionRequestDto, FunctionSearch>(arg);
                    search = FunctionConvertToSearchModel(arg);

                    //get ค่าแม่ของ  Function
                    if (arg.DomainId.HasValue)
                    {
                        search.Domain = _session.Get<Domain>(arg.DomainId.GetValueOrDefault());
                    }
                    _session.Clear();
                }

                using (_session)
                {
                    var dal = new FunctionDAL(_session, ProjectId);
                    list = dal.GetAll(search);

                    result.Data = new List<FunctionDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<Function, FunctionDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(FunctionConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<FunctionDto> UpdateFunction(FunctionDto arg)
        {
            var result = new ResponseDto<FunctionDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<FunctionDto, Function>(arg);
                    var obj = FunctionConvertToModel(arg);

                    var dal = new FunctionDAL(_session, ProjectId);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Function, FunctionDto>(obj);
                    result.Data = FunctionConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistFunction(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new FunctionDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new FunctionSearch { FuncName = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private FunctionDto FunctionConvertToDto(Function arg)
        {
            FunctionDto result = new FunctionDto();
            if (arg != null)
            {
                result.Id = arg.Id;
                result.FuncName = arg.FuncName;
                result.Description = arg.Description;
                if (arg.Domain != null)
                {
                    //DomainDto temp = new DomainDto();
                    //temp.Id = arg.Domain.Id;

                    //temp.DomainName = arg.Domain.DomainName;

                    //temp.Description = arg.Domain.Description;

                    //result.Domain = temp;
                    result.Domain = DomainConvertToDto(arg.Domain);
                }
                //result.FunctionStatus = arg.FunctionStatus;
                result.FunctionName = arg.FunctionName;
                if (arg.DomainLookup != null)
                {
                    //DomainDto temp = new DomainDto();
                    //temp.Id = arg.DomainLookup.Id;

                    //temp.DomainName = arg.DomainLookup.DomainName;

                    //temp.Description = arg.DomainLookup.Description;

                    //result.DomainLookup = temp;
                    result.DomainLookup = DomainConvertToDto(arg.DomainLookup);
                }
                result.IsActive = arg.IsActive;
                result.CreateById = arg.CreateById;
                result.CreateDate = arg.CreateDate;
            }
            return result;
        }

        private Function FunctionConvertToModel(FunctionDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<FunctionDto, Function>();
            Mapper.CreateMap<DomainDto, Domain>();
            Mapper.CreateMap<DomainDto, Domain>();
            Mapper.CreateMap<UserDto, User>();
            Function result = Mapper.Map<FunctionDto, Function>(arg);



            if (result.Domain != null)
            {
                result.Domain = (Domain)_session.Get("Domain", arg.Domain.Id);
            }

            if (result.DomainLookup != null)
            {
                result.DomainLookup = (Domain)_session.Get("Domain", arg.DomainLookup.Id);
            }


            return result;
        }

        private FunctionSearch FunctionConvertToSearchModel(GetAllFunctionRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllFunctionRequestDto, FunctionSearch>();
            FunctionSearch result = Mapper.Map<GetAllFunctionRequestDto, FunctionSearch>(arg);
            return result;
        }
        #endregion

        #region Domain methods

        public ResponseDto<DomainDto> AddDomain(DomainDto arg)
        {
            var result = new ResponseDto<DomainDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<DomainDto, Domain>(arg);

                    var obj = DomainConvertToModel(arg);

                    var dal = new DomainDAL(_session, ProjectId);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Domain, DomainDto>(obj);
                    result.Data = DomainConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<DomainDto> DeleteDomain(List<string> arg)
        {
            var result = new ResponseDto<DomainDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new DomainDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<DomainDto>> GetAllDomain(GetAllDomainRequestDto arg)
        {
            var result = new ResponseDto<List<DomainDto>>();
            var list = new List<Domain>();
            try
            {
                DomainSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllDomainRequestDto, DomainSearch>(arg);
                    search = DomainConvertToSearchModel(arg);
                }

                using (_session)
                {
                    var dal = new DomainDAL(_session, ProjectId);
                    list = dal.GetAll(search);

                    result.Data = new List<DomainDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<Domain, DomainDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(DomainConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<DomainDto> UpdateDomain(DomainDto arg)
        {
            var result = new ResponseDto<DomainDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<DomainDto, Domain>(arg);
                    var obj = DomainConvertToModel(arg);

                    var dal = new DomainDAL(_session, ProjectId);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Domain, DomainDto>(obj);
                    result.Data = DomainConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistDomain(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new DomainDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new DomainSearch { DomainName = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private DomainDto DomainConvertToDto(Domain arg)
        {
            DomainDto result = new DomainDto();
            if (arg != null)
            {
                result.Id = arg.Id;
                result.DomainName = arg.DomainName;
                result.Description = arg.Description;
                result.CreateById = arg.CreateById;
                result.IsActive = arg.IsActive;
                result.CreateDate = arg.CreateDate;
            }
            return result;
        }

        private Domain DomainConvertToModel(DomainDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<DomainDto, Domain>();
            Mapper.CreateMap<UserDto, User>();
            Domain result = Mapper.Map<DomainDto, Domain>(arg);




            return result;
        }

        private DomainSearch DomainConvertToSearchModel(GetAllDomainRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllDomainRequestDto, DomainSearch>();
            DomainSearch result = Mapper.Map<GetAllDomainRequestDto, DomainSearch>(arg);
            return result;
        }
        #endregion


        #region RoleUser methods

        public ResponseDto<RoleUserDto> AddRoleUser(RoleUserDto arg)
        {
            var result = new ResponseDto<RoleUserDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    // initial mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<RoleDto, Role>(arg);

                    var obj = RoleUserConvertToModel(arg);

                    var dal = new RoleUserDAL(_session);
                    dal.Add(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Role, RoleDto>(obj);
                    result.Data = RoleUserConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<RoleUserDto> DeleteRoleUser(List<string> arg)
        {
            var result = new ResponseDto<RoleUserDto>();
            using (_session.BeginTransaction())
            {
                try
                {
                    var obj = new RoleDAL(_session, ProjectId);
                    obj.Delete(arg);
                    _session.Transaction.Commit();
                    result.Status = true;
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<List<RoleUserDto>> GetAllRoleUser(GetAllRoleUserRequestDto arg)
        {
            var result = new ResponseDto<List<RoleUserDto>>();
            var list = new List<RoleUser>();
            try
            {
                RoleUserSearch search = null;
                if (arg != null)
                {
                    //var util = new MapperUtil(typeof(BaseGetAllRequestDto), typeof(BaseSearch));
                    //search = util.Map<GetAllRoleRequestDto, RoleSearch>(arg);
                    search = RoleUserConvertToSearchModel(arg);
                }

                using (_session)
                {
                    var dal = new RoleUserDAL(_session);
                    list = dal.GetAll(search);

                    result.Data = new List<RoleUserDto>();
                    if (list.Count > 0)
                    {
                        //var util = new MapperUtil(typeof(BaseEntity), typeof(BaseDto));
                        //foreach (var dto in list.Select(util.Map<Role, RoleDto>))
                        foreach (var item in list)
                        {
                            result.Data.Add(RoleUserConvertToDto(item));
                        }
                    }
                    result.Status = true;
                }
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        public ResponseDto<RoleUserDto> UpdateRoleUser(RoleUserDto arg)
        {
            var result = new ResponseDto<RoleUserDto>();

            using (_session.BeginTransaction())
            {
                try
                {
                    // initial Mapper
                    //var util = new MapperUtil(typeof(BaseDto), typeof(BaseEntity));
                    //var obj = util.Map<RoleDto, Role>(arg);
                    var obj = RoleUserConvertToModel(arg);

                    var dal = new RoleUserDAL(_session);
                    dal.Update(obj);
                    _session.Transaction.Commit();

                    result.Status = true;
                    //result.Data = util.Map<Role, RoleDto>(obj);
                    result.Data = RoleUserConvertToDto(obj);
                }
                catch (Exception ex)
                {
                    result.Status = false;
                    result.ErrorMessage = ex.Message;
                }
            }
            return result;
        }

        public ResponseDto<bool> ExistRoleUser(string pk)
        {
            var result = new ResponseDto<bool>();
            try
            {
                var dal = new RoleDAL(_session, ProjectId);

                var exist = false;
                if (!string.IsNullOrEmpty(pk))
                {
                    var search = new RoleSearch { RoleCode = StringParser.GetValue<String>(pk), EqPk = true, };
                    var list = dal.GetAll(search);
                    exist = list.Count > 0;
                }

                result.Data = exist;
                result.Status = true;
            }
            catch (Exception ex)
            {
                result.Status = false;
                result.ErrorMessage = ex.Message;
            }
            return result;
        }

        private RoleUserDto RoleUserConvertToDto(RoleUser arg)
        {
            RoleUserDto result = new RoleUserDto();
            if (arg != null)
            {
                Mapper.CreateMap<BaseDto, BaseEntity>();
                Mapper.CreateMap<RoleUserDto, RoleUser>();
                Mapper.CreateMap<RoleDto, Role>();
                //Mapper.CreateMap<PermissionDto, Permission>();
                //Mapper.CreateMap<FunctionDto, Function>();
                Mapper.CreateMap<UserDto, User>();
                result = Mapper.Map<RoleUser, RoleUserDto>(arg);

                //result.CreateDate = arg.CreateDate;
                //result.RoleStatus = arg.RoleStatus;
            }
            return result;
        }

        private RoleUser RoleUserConvertToModel(RoleUserDto arg)
        {
            Mapper.CreateMap<BaseDto, BaseEntity>();
            Mapper.CreateMap<RoleDto, Role>();
            //Mapper.CreateMap<PermissionDto, Permission>();
            //Mapper.CreateMap<FunctionDto, Function>();
            Mapper.CreateMap<UserDto, User>();
            RoleUser result = Mapper.Map<RoleUserDto, RoleUser>(arg);




            return result;
        }

        private RoleUserSearch RoleUserConvertToSearchModel(GetAllRoleUserRequestDto arg)
        {
            Mapper.CreateMap<BaseGetAllRequestDto, BaseSearch>();
            Mapper.CreateMap<GetAllRoleUserRequestDto, RoleUserSearch>();
            RoleUserSearch result = Mapper.Map<GetAllRoleUserRequestDto, RoleUserSearch>(arg);
            return result;
        }
        #endregion

    }
}